package com.peakmain.wanandroid.netmodule.net.http.download;


import android.os.Handler;
import android.os.Looper;

import com.andview.refreshview.utils.LogUtils;
import com.peakmain.baselibrary.utils.file.FileUtil;
import com.peakmain.wanandroid.netmodule.net.http.OkHttpManager;
import com.peakmain.wanandroid.netmodule.net.http.download.model.Progress;
import com.peakmain.wanandroid.netmodule.net.http.download.task.PriorityRunnable;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ThreadPoolExecutor;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * author ：Peakmain
 * version : 1.0
 * createTime：2020/2/22
 * mail:2726449200@qq.com
 * describe：
 */
public class DownloadTask implements Runnable {

    private static final int BUFFER_SIZE = 2048;

    private String url;//下载地址
    private File target;//文件保存地址
    private DownloadListener mDownloadListener;
    private Progress mProgress;
    private OkHttpClient mOkHttpClient;
    private ThreadPoolExecutor executor;
    private PriorityRunnable mPriorityRunnable;

    public DownloadTask(String url, File target, DownloadListener downloadListener) {
        this.url = url;
        this.target = target;
        this.mDownloadListener = downloadListener;
        mOkHttpClient = DownloadManager.getInstance().getDownOkhttpClient();
        mProgress = new Progress();
        mProgress.status = Progress.NONE;
        executor = DownloadManager.getInstance().getThreadPool().getExecutor();
    }

    /**
     * 开始下载
     */
    public void start() {
        //下载前检查状态
        if (mProgress.status == Progress.NONE || mProgress.status == Progress.PAUSE || mProgress.status == Progress.ERROR) {
            FileUtil.mkdirs(target.getParentFile());
            if (target.exists()) {
                target.delete();
            }
            if (mDownloadListener != null) {
                mDownloadListener.onStart();
            }
            mPriorityRunnable = new PriorityRunnable(mProgress.priority, this);
            //启动线程池
            executor.execute(mPriorityRunnable);
        } else if (mProgress.status == Progress.FINISH) {
            if (target == null) {
                postError();
            } else {
                if (target.exists() && target.length() == mProgress.totalSize) {
                    postFinish(target);
                } else {
                    postError();
                }
            }
        }

    }

    /**
     * 暂停下载
     */
    public void pause() {
        executor.remove(mPriorityRunnable);
        if (mProgress.status == Progress.LOADING) {
            mProgress.speed = 0;
            mProgress.status = Progress.PAUSE;
        } else {
            LogUtils.d("only the task with status LOADING(2) can pause, current status is");
        }
    }

    /**
     * 移除任务
     *
     * @param isDeleteFile 是否删除下载文件
     */
    public void removeTask(boolean isDeleteFile) {
        pause();
        //如果要删除文件 并且没有下载完成
        if (isDeleteFile && !isDownloadFinish() ) {
            FileUtil.deleteFiles(target);
            LogUtils.d( "删除下载文件" + (target != null ? target.getAbsolutePath() : ""));
        }
    }

    @Override
    public void run() {
        //如果保存文件地址为null 则直接返回
        if (target == null) {
            LogUtils.d("文件为空");
            postError();
            return;
        }
//        //构造请求
        final Request request = new Request.Builder()
                .url(url)
                .build();
        Response response;
        try {
            response = mOkHttpClient.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
            LogUtils.d("下载异常"+e.getMessage());
            postError();
            return;
        }
        int code = response.code();
        if (code == 404 || code >= 500) {
            postError();
            return;
        }
        ResponseBody body = response.body();
        if (body == null) {
            postError();
            return;
        }
        if (mProgress.totalSize == -1) {
            mProgress.totalSize = body.contentLength();
        }
        try {
            download(body.byteStream(), mProgress);
        } catch (IOException e) {
            e.printStackTrace();
            LogUtils.d("下载异常"+e.getMessage());
            postError();
            return;
        }
        //检测状态
        if (mProgress.status == Progress.PAUSE) {
            postPause(mProgress);
        } else if (mProgress.status == Progress.LOADING) {
            if (target.length() == mProgress.totalSize) {
                postFinish(target);
            } else {
                postError();
            }
        }
    }

    /**
     * 执行文件下载
     *
     */
    private void download(InputStream input, Progress progress) throws IOException {
        FileOutputStream out = new FileOutputStream(target);
        if (input == null || out == null) {
            return;
        }
        mProgress.status = Progress.LOADING;
        byte[] buffer = new byte[BUFFER_SIZE];
//        BufferedInputStream in = new BufferedInputStream(input, BUFFER_SIZE);
        int len;
        try {
            while ((len = input.read(buffer)) != -1 && mProgress.status == Progress.LOADING) {
                out.write(buffer, 0, len);
                Progress.changeProgress(progress, len, progress.totalSize, new Progress.Action() {
                    @Override
                    public void call(Progress progress) {
                        postLoading(progress);
                    }
                });
            }
            out.flush();
        } finally {
           out.close();
          input.close();
        }
    }

    /**
     * 处理下载中
     *
     */
    private void postLoading(final Progress progress) {
        if (mDownloadListener != null) {
            OkHttpManager.getInstance().getDelivery().execute(new Runnable() {
                @Override
                public void run() {
                    mDownloadListener.onProgress((int) (progress.fraction * 100));
                }
            });
        }
    }

    private void postPause(final Progress progress) {
        mProgress.speed = 0;
        mProgress.status = Progress.PAUSE;
    }

    /**
     * 下载完成
     *
     */
    private static final android.os.Handler HANDLER = new Handler(Looper.getMainLooper());
    private void postFinish(final File target) {
        mProgress.speed = 0;
        mProgress.fraction = 1.0f;
        mProgress.status = Progress.FINISH;
        if (mDownloadListener != null) {
            HANDLER.postDelayed(() -> mDownloadListener.onFinish(target), 100) ;
        }
    }

    /**
     * 处理下载错误
     */
    private void postError() {
        mProgress.speed = 0;
        mProgress.status = Progress.ERROR;
        if (mDownloadListener != null) {
            OkHttpManager.getInstance().getDelivery().execute(new Runnable() {
                @Override
                public void run() {
                    mDownloadListener.onError();
                }
            });
        }
    }

    /**
     * 返回下载是否完成
     *
     */
    public boolean isDownloadFinish() {
        return mProgress.status == Progress.FINISH;
    }
}
